using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace SerialPortCommunicationProject.Tools
{
    /// <summary>
    /// class for socket tcp communication
    /// children: SocketTcpServerCommunication, SocketTcpClientCommunication
    /// </summary>
    public abstract class SocketTcpCommunication : ICommunication
    {
        protected Socket socket;
        private protected byte[] sendBuffer;
        private protected byte[] receiveBuffer;

        public byte[] SendBuffer { get => sendBuffer; }
        public byte[] ReceiveBuffer { get => receiveBuffer; }

        public SocketTcpCommunication(int sendBufferSize, int receiveBufferSize)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sendBuffer = new byte[sendBufferSize];
            receiveBuffer = new byte[receiveBufferSize];
            IsOpen = false;
        }

        public SocketTcpCommunication() : this(100, 100) { }


        public bool IsOpen { get; set; }

        public abstract bool Open();

        public virtual bool Close()
        {
            if (IsOpen)
            {
                socket?.Close();
                socket?.Dispose();
                IsOpen = false;
            }
            return false;
        }

        public abstract void DataReceive();

        public abstract void Send(byte[] sendBuffer);

        public virtual bool TestConnected(Socket handler)
        {
            if (handler != null && handler.Connected)
            {
                try
                {
                    string msg = "heart package";
                    byte[] msgbytes = Encoding.ASCII.GetBytes(msg);
                    handler.Send(msgbytes, 0, 1, SocketFlags.None);
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
            return true;
        }

        public void Dispose()
        {
            socket.Dispose();
            socket = null;
        }
    }
}
